/**
 * Created by panshihao-cn on 2014/5/11 0011.
 */
var apiText = null;
var ModuleArray = new Array();
var ProjectURL = 'http://localhost:8080/WisdomClass/';

$(document).ready(function () {
    // 通过ajax的方式加载data内容
	
	$.ajax('getlastversion.php', {
		type : 'get',
		dataType : 'json',
		error : function(jqXHR, textStatus, errorThrown) {
			alert(errorThrown);
		},
		success : function(data) {
			if(data){
                if(localStorage.version){
                    var localVersion = JSON.parse(localStorage.version);
                    console.log('load   ',localVersion);
                    console.log('data   ',data);
                    if(localVersion.version >= data.version){
                        loadApiContent(localVersion);
                    }else{
                        loadApiContent(data);
                    }
                }else{
                    loadApiContent(data);
                }

			}else{
				alert('服务器上没有API文件，请检查！');
			}
		}
	});
	
});
/**
 * 加载API内容
 * @param version
 */
function loadApiContent(version){


        var url = 'read.php?version='+version.version+'&filename='+version.filename;

        $.ajax(url, {
            type : 'get',
            error : function(jqXHR, textStatus, errorThrown) {
                alert(errorThrown);
            },
            success : function(data) {
                localStorage.version = JSON.stringify(version);
                apiText = data;
                initEditor(data)
                initAPI();
                initEvent();
                $('.readtime').fadeIn(200).text('已更新文档 '+new Date().Format('yyyy-MM-dd hh:mm:ss'));
                setTimeout(function(){
                    $('.readtime').fadeOut(500);
                }, 5000);

                if(version.version){

                }

            }
        });

//    }


	// 将版本信息保存到localStorage
    startCheckNewVersion(version);
}
var checkNewVersionInterval = null;
/**
 * 启动持续检查新版本
 */
function startCheckNewVersion(version){

//    if(checkNewVersionInterval){
//       return;
//    }

//    // 每隔3 秒检查一次是否有新的API
//    checkNewVersionInterval = setInterval(function(){
//        
//    }, 1000);


	$.ajax('getlastversion.php', {
        type : 'get',
        dataType : 'json',
        error : function(jqXHR, textStatus, errorThrown) {
//            alert(errorThrown);
        	console.log(jqXHR, errorThrown);
        	
        },
        complete: function(){
        	// 当本次请求完成后，间隔2秒后继续下次请求
        	setTimeout(function(){
        		startCheckNewVersion();
        	}, 2000);
        },
        timeout: 20000,
        success : function(data) {
            if(data){
                if(localStorage.version){
                    var localVersion = JSON.parse(localStorage.version);
                    if(localVersion.version < data.version){
                        loadApiContent(data);
                    }
                }else{
                    loadApiContent(data);
                }

            }
        }
    });
	
	
}
/**
 * 初始化editor编辑器
 */
function initEditor(data){
	var apiEditor = $('#apiEditor');
	var apiLines = $('.api_editor_lines');

	var lines = data.split('\n');
	
	for(var i = 0 ; i < lines.length ; i ++){
		var line = lines[i];

        var dom = $('<div class="lines_item" index="'+i+'">'+i+'</div>');

        apiLines.append(dom);

        var bg = $('<div class="bg_item" index="'+i+'"></div>');

        if(i % 2 == 0){
            bg.addClass('bg_item_ddd');
        }else{
            bg.addClass('bg_item_eee');
        }

        $('.api_editor_bg').append(bg);


	}
	
	$('.api_textarea').val(data);
    $('.api_textarea').scroll(function(a,b,c){
        changeEditorSize();
    }).click(function(){
        $('.lines_item_focus').removeClass('lines_item_focus');
        $('.bg_item_focus').removeClass('bg_item_focus');
    });

}
/**
 * 选择行
 * @param line
 */
function selectEditorLine(line){
    var linesDom = $('.lines_item[index='+line+']');
    var bgDom = $('.bg_item[index='+line+']');

    $('.lines_item_focus').removeClass('lines_item_focus');
    $('.bg_item_focus').removeClass('bg_item_focus');

    if(linesDom.hasClass('lines_item_focus')){

    }else{
        linesDom.addClass('lines_item_focus');
        bgDom.addClass('bg_item_focus');
        $('.api_textarea').scrollTop(line * 20);
    }
    
    setTimeout(function(){
    	 $(window).scrollTop($(window).scrollTop() - 40);
    }, 10);
   

}
/**
 * 修改 编辑器的大小
 */
function changeEditorSize(){

    $('.api_editor_lines').scrollTop($('.api_textarea').scrollTop());
    $('.api_editor_bg').scrollTop($('.api_textarea').scrollTop());


}
String.prototype.trim2 = function () {
    return this.replace(/(^\s*)|(\s*$)/g, "");
}
// 对Date的扩展，将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
// 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子：
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function(fmt) { //author: meizz
    var o = {
        "M+" : this.getMonth() + 1, //月份
        "d+" : this.getDate(), //日
        "h+" : this.getHours(), //小时
        "m+" : this.getMinutes(), //分
        "s+" : this.getSeconds(), //秒
        "q+" : Math.floor((this.getMonth() + 3) / 3), //季度
        "S" : this.getMilliseconds()
        //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
            .substr(4 - RegExp.$1.length));
    for ( var k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(RegExp.$1,
                (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k])
                    .substr(("" + o[k]).length)));
    return fmt;
}
var delay = 2000;
var tempTime = 0;
var delayInterval = null;
/**
 * 延迟保存
 * 默认为 没有修改后 2秒 绘制并保存界面
 */
function delayAuto(){

    if(!delayInterval){
        delayInterval = setInterval(function(){

            if(tempTime >= delay){
                initAPI();
                saveForServer();
                tempTime = 0;
                clearInterval(delayInterval);
                delayInterval = null;
                $('#apiAutoSave .savetime').fadeIn(200).show().text('自动保存于 '+new Date().Format('yyyy-MM-dd hh:mm:ss'));
                setTimeout(function(){
                    $('#apiAutoSave .savetime').fadeOut(500);
                }, 5000);
//                $('#apiAutoSave .delay').text('');
            }else{
//                $('#apiAutoSave .delay').text(" "+((delay-tempTime)/ 1000 +" 秒后自动保存"));
                tempTime += 100;
            }

        }, 100);
    }else {
        tempTime = 0;
    }

}
var evented = false;
/**
 * 初始化事件
 */
function initEvent(){
	if(evented){
		return;
	}
	
	evented = true;
    $('#all_contraction_0').click(function(){
        $('.contraction').attr('state',1).click();
    });
    $('#all_contraction_1').click(function(){
        $('.contraction').attr('state',0).click();
    });
    $('#api_contraction_0').click(function(){
        $('#all_contraction_1').click();
        $('.api_contraction').attr('state',1).click();
    });
    $('#api_contraction_1').click(function(){
        $('#all_contraction_1').click();
        $('.api_contraction').attr('state',0).click();
    });
    $('#edit_mode').click(function(){
        if($('#apiEditor:visible').size() > 0){
            $('#apiEditor').hide();
            $('#apiContext').css({
                'width': '82%',
                'margin-left': 0
            });
            console.log('编辑模式');
            $(this).text('编辑模式');
        }else{
            $('#apiEditor').show();
            $('#apiContext').css({
                'width': '30%',
                'margin-left': '52%'
            });
            $(this).text('阅读模式');
            console.log('阅读模式');

            changeEditorSize();
        }
    });


    $('.api_textarea').keydown(function(e){
        if(e.keyCode == 9){
//        	insertContent(this, '　　', 0);
        }
        

    }).keyup(function(){

        if($(this).val() != apiText){
            apiText = $(this).val();
            // 延迟自动保存
            delayAuto();
            
        }
    });

    $('#all_gototop').click(function(){
        $(window).scrollTop(0);
        $('#apiMenu').scrollTop(0);
        $('#apiContext').scrollTop(0);
    });
    
    
    $('#console_list').click(function(){
    	
    	
    });
    
//    $('.api_textarea').css('height',$(window).height() - 20);
  
}
/**
 * 传入内容
 * @param textarea
 * @param content
 * @param difference
 */
function insertContent(textarea, content, difference){
	var curStart = textarea.selectionStart;
	var curEnd = textarea.selectionEnd;
	
	textarea.value = textarea.value.slice(0, curStart + difference) + content + textarea.value.slice(curEnd + difference)
	
	textarea.selectionStart = curStart + difference + content.length;
	textarea.selectionEnd = curEnd + difference + content.length;
	
	
	$(textarea).click().focus();
}
/**
 * 插入文本
 */
function insertText(textarea,str,cursor) { 
	
	console.log(cursor);
	
	var value = $(textarea).val();
	value = value.slice(0, cursor.start) + str + value.slice(cursor.end);
	
	$(textarea).val(value);
} 
//返回光标所在位置
/**//*
* source: http://blog.csdn.net/liujin4049/archive/2006/09/19/1244065.aspx
* acknowledges for Marshall 
* example: 
* var myTextBox = document.getElementById("MyTextBoxID");
* var cursPos = $CursorPosition(myTextBox);
* alert(cursPos.item[0] + " " + cursPos.item[1]);
* // OR
* alert(cursPos.start + " " + cursPos.end); 
*/
function $CursorPosition(textBox){ 
    var start = 0, end = 0;
    //如果是Firefox(1.5)的话，方法很简单
    if(typeof(textBox.selectionStart) == "number"){
        start = textBox.selectionStart;
        end = textBox.selectionEnd;
    }
//下面是IE(6.0)的方法，麻烦得很，还要计算上'\n'
    else if(document.selection) {
        var range = document.selection.createRange();
        if(range.parentElement().id == textBox.id) {
            // create a selection of the whole textarea
            var range_all = document.body.createTextRange();
            range_all.moveToElementText(textBox);
            //两个range，一个是已经选择的text(range)，一个是整个textarea(range_all)
            //range_all.compareEndPoints()比较两个端点，如果range_all比range更往左(further to the left)，则 
            //返回小于0的值，则range_all往右移一点，直到两个range的start相同。
            // calculate selection start point by moving beginning of range_all to beginning of range
            for (start=0; range_all.compareEndPoints("StartToStart", range) < 0; start++)
                range_all.moveStart('character', 1);
                // get number of line breaks from textarea start to selection start and add them to start
                // 计算一下\n
                for (var i = 0; i <= start; i ++) {
                if (textBox.value.charAt(i) == '\n')
                    start++;
            }
            // create a selection of the whole textarea
            var range_all = document.body.createTextRange();
            range_all.moveToElementText(textBox);
            // calculate selection end point by moving beginning of range_all to end of range
            for (end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; end ++) {
                range_all.moveStart('character', 1);
            }
            // get number of line breaks from textarea start to selection end and add them to end
            for (var i = 0; i <= end; i ++) {
                if (textBox.value.charAt(i) == '\n')
                    end ++;
            }
        }
    }
    //return [start, end]; // 包括选中区域的起始位置
    // modified to return as Object
    return { "start": start, "end": end, "item": [start, end] };
}
/**
 * 将当前信息保存下来
 */
function saveForServer(){

    $.ajax('save.php', {
        type: 'post',
        data: {
            content: apiText
        },
        dataType : 'json',
        error : function(jqXHR, textStatus, errorThrown) {
            console.log(jqXHR);
        },
        success : function(data) {
            if(data){
               localStorage.version = JSON.stringify(data);
            }
            console.log(data);
        }
    });

}
/**
 * 初始化API
 */
function initAPI() {

    // 调用解析方法 返回结果数组
    var startTime = new Date().getTime();
    ModuleArray = parseContent(apiText);
    var endTime = new Date().getTime();

    //console.log(ModuleArray);
//    console.log('解析完毕，共 '+ModuleArray.length +'个Module，用时 '+(endTime - startTime) + 'ms');

    var apiCount = 0;
    var completeCount = 0;
    for(var i = 0 ; i < ModuleArray.length ; i ++){
        var module = ModuleArray[i];
        apiCount += module.apis.length;
        var apis = module.apis;
        for(var a = 0 ; a < apis.length ; a ++){
            var api = apis[a];

            if(api.state == 'true'){
                completeCount ++;
            }

        }


    }





    $('#apiResult').text('解析完毕，共 '+ModuleArray.length +'个Module '+apiCount+' 个API，用时 '+(endTime - startTime) + 'ms' + ' 完成度： '+completeCount+' /'+apiCount);


    changeUI(ModuleArray);



}

/**
 * 根据传入的moduleArray修改界面
 * @param moduleArray
 */
function changeUI(moduleArray){
    var apiContext = $('#apiContext');
    // 清空apiContext
    apiContext.empty();
    // 清空apiMenu
    $('.menu_item').remove();
//    $('#apiMenu').css({
//        'height': $(window).height() - 40
//    });

    // 遍历notes
    for(var i = 0 ; i < moduleArray.notes.length ; i ++){
        var note = moduleArray.notes[i];

        var noteDom = $('<div class="note"></div>');

        noteDom.attr('id','note_'+i);

        var noteMenu = $('<a href="#note_'+i+'" class="menu_item menu_api">'+note.name+'</a>');
        
        noteMenu.attr('line',note.line).attr('index',note.index).click(function(){
        	var line = $(this).attr('line');
            selectEditorLine(line);
        	
        });
        
        $('#apiMenu').append(noteMenu);


        var noteNameDom = $('<div class="note_name">'+note.name+'</div>');
        var noteDescDom = $('<div class="note_desc">'+note.desc+'</div>');

        noteDom.append(noteNameDom).append(noteDescDom);

        apiContext.append(noteDom);

    }

    var abc = "";
    //遍历 modulearray

    for(var i = 0 ; i < moduleArray.length ; i ++){
        var module = moduleArray[i];

        var moduleDom = $('<div class="module"></div>');
        // 设置module的ID
        moduleDom.attr('id', 'module_'+i);
        
        var moduleMenu = $('<a href="#module_'+i+'" class="menu_item menu_module">'+module.name+' '+module.mapping+'</a>');

        moduleMenu.attr('line',module.line).attr('index',module.index).click(function(){
            var line = $(this).attr('line');
            selectEditorLine(line);

        });

        $('#apiMenu').append(moduleMenu);


        var moduleContractionDom = $('<div class="module_contraction contraction">-</div>');

        moduleDom.append(moduleContractionDom);

        // 设置收缩按钮的样式
        moduleContractionDom.css({
            'float': 'right',
            'font-size': '30px',
            'cursor': 'pointer'
        }).attr('state', 1).click(function(){
            var pthis = $(this);
            var state = $(this).attr('state');
            switch  (state){
                case '0':
                    // 0代表处于收缩状态
                    pthis.parent().find('.module_apis').show();
                    pthis.attr('state',1);
                    pthis.text('-');
                    break;
                case '1':
                    // 1代表处于张开状态

                    pthis.parent().find('.module_apis').hide();
                    pthis.attr('state',0);
                    pthis.text('+');
                    break;
            }
        });


        var moduleNameDom = $('<div class="module_name">'+module.name+'</div>');
        var moduleMappingDom = $('<div class="module_mapping"><span>模块映射　</span><b>'+module.mapping+'</b></div>');
        var moduleDescDom = $('<div class="module_desc">'+module.desc+'</div>');
        //将module的基本属性dom加入到根dom中
        moduleDom.append(moduleNameDom).append(moduleMappingDom).append(moduleDescDom);

        var moduleApisDom = $('<div class="module_apis"></div>');

        for(var a = 0 ; a < module.apis.length ; a ++){
            var api = module.apis[a];

            var console_debug = module.mapping+ '_'+api.mapping + '('+'"'+module.mapping+'","'+api.mapping+'","'+api.desc+'",'+api.token+', WisdomClass.Method_'+api.method+''+'),\n';
            abc += console_debug;
            
            var apiDom = $('<div class="api"></div>');

            // 设置api的ID
            apiDom.attr('id', 'module_'+i+'api_'+a);

            var menu_state = '';
            if(api.state == 'true'){
                menu_state = '<span style="color: green">(已实现)</span>';
            }else{
                menu_state = '<span style="color: orangered">(未实现)</span>';
            }

            var apiMenu = $('<a href="#module_'+i+'api_'+a+'" class="menu_item menu_api">'+api.name+' '+api.mapping+' '+menu_state+'</a>');

            apiMenu.attr('line',api.line).attr('index',api.index).click(function(){
                var line = $(this).attr('line');
                selectEditorLine(line);

            });


            $('#apiMenu').append(apiMenu);


            var apiContractionDom = $('<div class="api_contraction contraction">-</div>');

            apiDom.append(apiContractionDom);

            // 设置收缩按钮的样式
            apiContractionDom.css({
                'float': 'right',
                'font-size': '30px',
                'cursor': 'pointer'
            }).attr('state', 1).click(function(){
                var pthis = $(this);
                var state = $(this).attr('state');
                switch  (state){
                    case '0':
                        // 0代表处于收缩状态
                        pthis.parent().find('.api_options').show();
                        pthis.attr('state',1);
                        pthis.text('-');
                        break;
                    case '1':
                        // 1代表处于张开状态

                        pthis.parent().find('.api_options').hide();
                        pthis.attr('state',0);
                        pthis.text('+');
                        break;
                }
            });



            var apiNameDom = $('<div class="api_name">'+api.name+'</div>');
            if(api.state == 'true'){
                var apiStateDom = $('<span class="api_state yes">已实现</span>').appendTo(apiNameDom);

            }else if(api.state == 'false'){
                var apiStateDom = $('<span class="api_state no">未实现</span>').appendTo(apiNameDom)
            }
            var apiMappingDom = $('<div class="api_mapping"><span>'+api.method+'</span><b>'+module.mapping+'/'+api.mapping+'</b></div>');

            var apiDescDom = $('<div class="api_desc">'+api.desc+'</div>');


            // 将api的基本属性dom加入到api根dom中
            apiDom.append(apiNameDom).append(apiMappingDom).append(apiDescDom)

            if(api.token == true){
                var apiTokenDom = $('<div class="api_token_yes"><span>ValidateToken 必须</span></div>').appendTo(apiDom);
            }else{
                var apiTokenDom = $('<div class="api_token_no"><span>ValidateToken 可选</span></div>').appendTo(apiDom);
            }


            var apiOptionsDom = $('<div class="api_options"></div>');

            for(var o = 0 ; o < api.options.length ; o ++){
                var option = api.options[o];

                var optionDom = $('<div class="option"></div>');

                // 设置option的ID
                optionDom.attr('id', 'module_'+i+'api_'+a+'option_'+o);
//                $('#apiMenu').append($('<a href="#module_'+i+'api_'+a+'option_'+o+'" class="menu_item menu_option"><span>|————</span>'+option.name+'</a>'));

                var optionContractionDom = $('<div class="option_contraction contraction">-</div>');

                optionDom.append(optionContractionDom);

                // 设置收缩按钮的样式
                optionContractionDom.css({
                    'float': 'right',
                    'font-size': '30px',
                    'cursor': 'pointer'
                }).attr('state', 1).click(function(){
                    var pthis = $(this);
                    var state = $(this).attr('state');
                    switch  (state){
                        case '0':
                            // 0代表处于收缩状态
                            pthis.parent().find('.itemsitems,.demo_item').show();
                            pthis.attr('state',1);
                            pthis.text('-');
                            break;
                        case '1':
                            // 1代表处于张开状态

                            pthis.parent().find('.itemsitems,.demo_item').hide();
                            pthis.attr('state',0);
                            pthis.text('+');
                            break;
                    }
                });


                var optionNameDom = $('<div class="option_name"><span>'+option.name+'</span></div>');

                optionDom.append(optionNameDom);
                // 将optionDom加入optionsDom
                apiOptionsDom.append(optionDom);

                if(option.items.length == 0){
                    continue;
                }
                var firstType = option.items[0].type;

                // 根据不同的type 构造不同的效果
                switch (firstType){
                    case '=':
                        var optionValueEqualDom = $('<div class="option_value_equal">'+option.items[0].value+'</div>');
                        optionDom.append(optionValueEqualDom);
                        optionContractionDom.hide();
                        break;
                    case '+':
                        var optionItemsDom = $('<div class="option_items itemsitems"></div>');

                        for(var it = 0 ; it < option.items.length ; it ++){
                            var item = option.items[it];

                            var itemDom = $('<div class="item"></div>');
                            var itemFieldDom = $('<div class="item_field"></div>');
                            var itemNameDom = $('<span class="item_name">'+item.name+'</span>');

                            itemFieldDom.append(itemNameDom);


                            var itemRequiredDom = $('<span class="item_required">'+(item.required == 'true' ? '必要字段':'可选字段')+'</span>');
                            itemFieldDom.append(itemRequiredDom);
                            var itemFieldTypeDom = $('<span class="item_fieldtype">'+item.fieldType+'</span>');
                            itemFieldDom.append(itemFieldTypeDom);

                            if(item.fieldType == 'datetime'){
                                item.defaultValue = item.defaultValue.replace('_',' ');
                            }


                            if(item.fieldType == 'object' || item.fieldType == 'array'){
                                var itemDescDom = $('<div class="item_desc">'+item.desc+'</div>');
                            }else{
                                var itemDescDom = $('<div class="item_desc">'+item.desc+'<span style="color:orangered">　　演示值：'+item.defaultValue+'</span></div>');
                            }



                            itemDom.append(itemFieldDom).append(itemDescDom);


                            if(item.fieldType == 'object' || item.fieldType == 'array'){

                                changeItemObject(0, item, itemDom);
                            }



                            optionItemsDom.append(itemDom);
                        }


                        optionDom.append(optionItemsDom);
                        break;
                    case 'e':

                        var optionErrorItemsDom = $('<div class="option_erroritems itemsitems"></div>');

                        for(var it = 0 ; it < option.items.length ; it ++){
                            var ErrorItem = option.items[it];

                            var ErrorItemDom = $('<div class="erroritem"></div>');
                            var ErrorItemNameDom = $('<div class="erroritem_name"><span>'+ErrorItem.name+'</span></div>');
                            var ErrorItemDescDom = $('<div class="erroritem_desc">'+ErrorItem.desc+'</div>');

                            ErrorItemDom.append(ErrorItemNameDom).append(ErrorItemDescDom);

                            optionErrorItemsDom.append(ErrorItemDom);
                        }

                        optionDom.append(optionErrorItemsDom);
                        break;
                    case 'j':

                        var optionJsonItemsDom = $('<div class="option_jsonitems itemsitems"></div>');

                        for(var it = 0 ; it < option.items.length ; it ++){
                            var JsonItem = option.items[it];

                            var JsonItemDom = $('<div class="jsonitem"></div>');
                            var JsonItemNameDom = $('<div class="jsonitem_name"><span>'+JsonItem.name+'</span></div>');
                            var JsonItemDescDom = $('<div class="jsonitem_desc">'+JsonItem.json+'</div>');

                            JsonItemDom.append(JsonItemNameDom).append(JsonItemDescDom);

                            optionJsonItemsDom.append(JsonItemDom);
                        }

                        optionDom.append(optionJsonItemsDom);
                        break;
                    default :
                        break;
                }




                changeJSONPreview(option, optionDom, api.method, module, api);

            }

            apiDom.append(apiOptionsDom);

            // 将apiDom添加到moduleApisDom中
            moduleApisDom.append(apiDom);
        }
        // 将moduleApisDom添加到module根dom
        moduleDom.append(moduleApisDom);

        // 将moduleDom添加到apiContext中
        apiContext.append(moduleDom);


    }


//    console.log(abc);

}

/**
 * 根据传入的内容进行解析，返回解析后的array对象
 * @param content
 */
function parseContent(content) {
    // 首先根据换行符分割字符串
    var lines = content.split('\n');
    var responseArray = new Array();
    var module = null;
    var api = null;
    var option = null;
    var item = null;

    var index = 0;
    
    // 然后遍历Lines
    for (var i = 0; i < lines.length; i++) {
        // 为了识别方便，这里将使用trim
        var line = lines[i].trim();
        // 判断line是否是空行
        if (line.length <= 0) {
            continue;
        }
        index += lines[i].length;


        // 将line按空格进行分割
        var params = line.split(/\s/);

        // 如果params的length <= 1，则代表这是一行不规则的内容，直接跳过
        if (params.length < 1 ) {
            continue;
        }

        // 判断首字符
        var firstChar = params[0];

        // 获取 + 在首字符中出现的个数
        var plusCount = getCharCount(firstChar, '+');

        // 判断 当前行的首字符是否处于递归状态
        if(firstChar.length > 1 && plusCount >= 1 ){
            // 取得 首字符的最后一个字母

            if(!item){
                // 如果item为空，则跳出本行
                continue;
            }

            if(!item.fieldType || (item.fieldType != 'object' && item.fieldType != 'array')){
                // 承载递归信息的item的fieldType如果为空 或者不为object和array 则跳出本行
                 continue;
            }

            if(!item.plusContent){
                item.plusContent = '';
            }
            //console.log(item.name,line);
            item.plusContent += '\n'+line;
            continue;
        }



        switch (firstChar) {
            case '!':
                var type = params[1];

                switch (type){
                    case 'Start':
                        break;
                    case 'End':
                        // 最后一行的时候执行item 解析
                        if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                            item.plus = parsePlusObject(1, item.plusContent);
                        }
                        break;
                }
                break;
            case '!%':
                if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                    item.plus = parsePlusObject(1, item.plusContent);
                }
                // % 代表项目级注释说明，在整个API工具的顶部显示，无论api.txt的哪个位置定义都会显示到顶部
                var note = new Object();
                note.line = i;
                note.index = index;
                note.lineCount = lines[i].length;
                // 提取name
                note.name = params[1];
                if(!note.name){
                    console.log(note.name + ' 格式不匹配，跳过该note的解析,行号：'+i);
                    note = null;
                    continue;
                }

                // 提取desc
                note.desc = params[2];
                if(!note.desc){
                    console.log(note.name + ' 格式不匹配，跳过该note的解析,行号：'+i);
                    note = null;
                    continue;
                }
                if(!responseArray.notes){
                    responseArray.notes = new Array();
                }

                responseArray.notes.push(note);


                break;
            case '#':
                if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                    item.plus = parsePlusObject(1, item.plusContent);
                }
                // 如果是# 则代表一个新的module开始
                module = new Object();
                module.line = i;
                module.index = index;
                module.lineCount = lines[i].length;
                // 提取name
                module.name = params[1];
                if(!module.name){
                    console.log(module.name + ' 格式不匹配，跳过该module的解析,行号：'+i);
                    module = null;
                    continue;
                }

                if (!params[2] || params[2].indexOf('[') == -1 || params[2].indexOf(']') == -1) {
                    // 代表 #的格式错误，跳过改行，并且将module设置为null;
                    console.log(module.name + ' 格式不匹配，跳过该module的解析,行号：'+i);
                    module = null;
                    continue;
                }
                // 提取module的mapping,提取[]中的内容
                module.mapping = params[2].replace(/\[|\]/g, '');

                // 如果params[3]不为空，则将其设置为desc
                if (params[3]) {
                    module.desc = params[3];
                }else{
                    console.log(module.name + ' 格式不匹配，跳过该module的解析,行号：'+i);
                    module = null;
                    continue;
                }

                // 为module实例化一个array
                module.apis = new Array();

                responseArray.push(module);

                break;
            case '##':
                // 如果是## 则代表一个新的API开始
                if (!module) {
                    // 如果module为null 则跳出该行的解析
                    api = null;
                    continue;
                }

                if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                    item.plus = parsePlusObject(1, item.plusContent);
                }

                api = new Object();
                api.line = i;
                api.index = index;
                api.lineCount = lines[i].length;
                // 提取name
                api.name = params[1];

                if(!api.name){
                    console.log(api.name + ' 格式不匹配，跳过该api的解析,行号：'+i);
                    api = null;
                    continue;
                }
                if (!params[2] || params[2].indexOf('[') == -1 || params[2].indexOf(']') == -1) {
                    // 代表 ##的格式错误，跳过改行，并且将api设置为null;
                    console.log(api.name + ' 格式不匹配，跳过该api的解析,行号：'+i);
                    api = null;
                    continue;
                }

                // 提取Api名,提取[]中的内容
                var value = params[2].replace(/\[|\]/g, '');
                //提取URL和Method
                var valueSplit = value.split(',');
                if(valueSplit.length <= 1){
                    api.mapping = valueSplit[0];
                    api.method = 'GET';
                    api.token = false;
                }else{
                    api.mapping = valueSplit[0];
                    api.method = valueSplit[1];
                    api.token = valueSplit[2] ? !(valueSplit[2] == 'false') : false;
                }
                // 如果params[3]不为空，则将其设置为desc
                if (params[3]) {
                    api.desc = params[3];
                }else{
                    console.log(api.name + ' 格式不匹配，跳过该api的解析,行号：'+i);
                    api = null;
                    continue;
                }

                if(params[4]){
                    api.state = params[4];
                }else{
                    api.state = 'false';
                }


                // 为api实例化一个array
                api.options = new Array();
                // 然后将 api push到 module中
                module.apis.push(api);
                break;
            case '@':
                // 如果是 @ 则代表 API中一个新的配置项即将开始
                if (!api) {
                    // 如果api为null 则跳出该行的解析
                    option = null;
                    continue;
                }

                if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                    item.plus = parsePlusObject(1, item.plusContent);
                }

                option = new Object();

                // 提取name
                option.name = params[1];

                if(!option.name){
                    console.log(option.name + ' 格式不匹配，跳过该option的解析,行号：'+i);
                    option = null;
                    continue;
                }


                // 如果params[2]不为空，则将其设置为value
                if (params[2]) {
                    option.value = params[2];
                }

                // 为options实例化一个array
                option.items = new Array();
                // 然后将 api push到 module中
                api.options.push(option);

                break;
            case '+':
                // 如果 + 则代表是选项的值列表开始
                if (!option) {
                    // 如果 option为null 则跳出该行的解析
                    item = null;
                    continue;
                }

                if(item != null && (item.fieldType == 'object' || item.fieldType == 'array')){
                    item.plus = parsePlusObject(1, item.plusContent);
                }
                item = new Object();
                // 设置item的type
                item.type = '+';
                // 提取name
                item.name = params[1];

                if(!item.name){
                    console.log(item.name + ' 格式不匹配，跳过该item的解析,行号：'+i);
                    item = null;
                    continue;
                }

                // 判断params[2]的类型
                if (!params[2] || params[2].indexOf('(') == -1 || params[2].indexOf(')') == -1) {
                    // 代表 +的格式错误，跳过改行，并且将item设置为null;
                    console.log(item.name + ' 格式不匹配，跳过该item的解析');
                    item = null;
                    continue;
                }

                // 提取item参数,提取[]中的内容
                var itemValue = params[2].replace(/\(|\)/g, '');
                // itemValue理论上是采用 逗号进行分割，其中的参数的个数是不定的
                var itemValues = itemValue.split(',');

                // 参数列表的第1个字段代表 required，第2个字段类型
                if(itemValues.length < 2){
                    // 参数列表的长度必须为2
                    console.log(item.name + ' 格式不匹配，跳过该item的解析');
                    item = null;
                    continue;
                }

                // 是否必须
                item.required = itemValues[0];
                // 字段类型
                item.fieldType = itemValues[1];

                if(itemValues[2] != undefined){
                    item.defaultValue = itemValues[2];
                }else{
                    item.defaultValue = '';
                }



                // 判断 params[3] 是否存在，存在则为 desc
                if (params[3]) {
                    item.desc = params[3];
                }else{
                    console.log(item.name + ' 格式不匹配，跳过该item的解析,行号：'+i);
                    item = null;
                    continue;
                }




                // 将item 添加至option
                option.items.push(item);

                break;

            case 'e':
                // 如果 e 则代表是选项的值列表开始
                if (!option) {
                    // 如果 option为null 则跳出该行的解析
                    item = null;
                    continue;
                }

                item = new Object();
                // 设置item的type
                item.type = 'e';
                // 提取name
                item.name = params[1];
                if(!item.name){
                    console.log(item.name + ' 格式不匹配，跳过该item的解析,行号：'+i);
                    item = null;
                    continue;
                }

                // 提取desc
                item.desc = params[2];
                if(!item.desc){
                    console.log(item.name + ' 格式不匹配，跳过该item的解析,行号：'+i);
                    item = null;
                    continue;
                }

                // 将item 添加至option
                option.items.push(item);
                break;
            case '=':
                // 如果 e 则代表是选项的值列表开始
                if (!option) {
                    // 如果 option为null 则跳出该行的解析
                    item = null;
                    continue;
                }

                item = new Object();
                // 设置item的type
                item.type = '=';
                // 提取name
                item.value = params[1];
                if(!item.value){
                    console.log(item.value + ' 格式不匹配，跳过该item的解析,行号：'+i);
                    item = null;
                    continue;
                }


                // 将item 添加至option
                option.items.push(item);
                break;
            default :
                break;
        }


    }



    return responseArray;
}

/**
 * 解析Plus item 返回Object
 * @param line
 */
function parsePlusItem(params){
    var item = new Object();

    // 设置item的type
    item.type = '+';
    // 提取name
    item.name = params[1];

    if (!item.name) {
        console.log(item.name + ' 格式不匹配，跳过该item的解析，'+params);
        item = null;
        return null;
    }

    // 判断params[2]的类型
    if (!params[2] || params[2].indexOf('(') == -1 || params[2].indexOf(')') == -1) {
        // 代表 +的格式错误，跳过改行，并且将item设置为null;
        console.log(item.name + ' 格式不匹配，跳过该item的解析');
        item = null;
        return null;
    }

    // 提取item参数,提取[]中的内容
    var itemValue = params[2].replace(/\(|\)/g, '');
    // itemValue理论上是采用 逗号进行分割，其中的参数的个数是不定的
    var itemValues = itemValue.split(',');

    // 参数列表的第1个字段代表 required，第2个字段类型
    if (itemValues.length < 2) {
        // 参数列表的长度必须为2
        console.log(item.name + ' 格式不匹配，跳过该item的解析');
        item = null;
        return null;
    }

    // 是否必须
    item.required = itemValues[0];
    // 字段类型
    item.fieldType = itemValues[1];


    // 判断 params[3] 是否存在，存在则为 desc
    if (params[3]) {
        item.desc = params[3];
    } else {
        console.log(item.name + ' 格式不匹配，跳过该item的解析');
        item = null;
        return null;
    }

    if(itemValues[2] != undefined){
        item.defaultValue = itemValues[2];
    }else{
        item.defaultValue = '';
    }

    return item;
}

/**
 * 根据 content 返回 jsonObject对象
 * @param index
 * @param content
 */
function parsePlusObject(index, content){
    if(!content){
        return {};
    }
    var contentSplit = content.split(/\n/);

    var objectArray = new Object();
    objectArray.plus = [];

    var item = null;

    var countArray = [];

    var currentItem = null;


    // 内容分割循环
    for(var i = 0 ; i < contentSplit.length ; i ++){
        var line = contentSplit[i].trim();

        var params = line.split(/\s/);

        if(params.length == 0 || line.length == 0){
            continue;
        }

        // 取得每行的首字符
        var firstChar = params[0];

        // 取得 + 数量
        var plusCount = getCharCount(firstChar, '+');
        var plusType = firstChar.charAt(firstChar.length - 1);

        //console.log(params);

        switch (plusType){
            case '+':

                var item = parsePlusItem(params);
                if(!item){
                    //console.log(line);
                    continue;
                }
                var lastItem = currentItem;
                if(!lastItem){
                    lastItem = objectArray.plus[objectArray.length - 1];
                }

                if(!lastItem){
                    item.plusCount = plusCount;
                    item.parent = objectArray;
                    currentItem = item;
                    countArray[plusCount] = objectArray;
                    objectArray.plus.push(item);
                }else{
                    if(lastItem.plusCount == plusCount){

                        if(!lastItem.parent.plus){
                            lastItem.parent.plus = new Array();
                        }

                        item.parent = lastItem.parent;
                        item.plusCount = plusCount;
                        lastItem.parent.plus.push(item);
                        currentItem = item;
                        countArray[plusCount] = lastItem.parent;

                    }else if(lastItem.plusCount < plusCount){
                        if(!lastItem.plus){
                            lastItem.plus = new Array();
                        }

                        item.parent = lastItem;
                        item.plusCount = plusCount;
                        lastItem.plus.push(item);
                        currentItem = item;
                        countArray[plusCount] = lastItem;

                    }else if(lastItem.plusCount > plusCount){
                        if(!countArray[plusCount].plus){
                            countArray[plusCount].plus = new Array();
                        }

                        item.parent = countArray[plusCount];
                        item.plusCount = plusCount;
                        countArray[plusCount].plus.push(item);
                        currentItem = item;
                        countArray[plusCount] = countArray[plusCount];
                    }


                }


                break;
        }

    }


    return objectArray.plus;

}


/**
 * 返回字符char在Src中出现的次数
 * @param src
 * @param char
 */
function getCharCount(src, char){

    var count = 0;
    for(var i = 0 ; i < src.length ; i ++){
        if(char == src.charAt(i)){
            count ++;
        }
    }

    return count;

}
/**
 * 判断 src中是否包含有charArray中的所有元素，全部包含返回true 否则返回false
 * @param src
 * @param charArray
 */
function checkInclude(src, charArray){

    var result = 0;
    for(var i = 0 ; i < src.length ; i ++){

        var char = src.charAt(i);

        if($.inArray(charArray. char) != -1){
            result ++;
        }

    }

    return result == charArray.length;


}

/**
 * 改变界面，实现递归parameter
 * @param item
 * @param itemDom
 */
function changeItemObject(index, data, parentDom){

    if(!data.plus){
        return;
    }

    for(var it = 0 ; it < data.plus.length ; it ++){
        var item = data.plus[it];

        var itemDom = $('<div class="item"></div>');

        var itemFieldDom = $('<div class="item_field"></div>');
        var itemNameDom = $('<span class="item_name">'+item.name+'</span>');

        itemFieldDom.append(itemNameDom);


        var itemRequiredDom = $('<span class="item_required">'+(item.required == 'true' ? '必要字段':'可选字段')+'</span>');
        itemFieldDom.append(itemRequiredDom);
        var itemFieldTypeDom = $('<span class="item_fieldtype">'+item.fieldType+'</span>');
        itemFieldDom.append(itemFieldTypeDom);

        var itemDescDom = $('<div class="item_desc">'+item.desc+'<span style="color:orangered">　　演示值：'+item.defaultValue+'</span></div>');

        itemDom.append(itemFieldDom).append(itemDescDom);


        if(index % 2 == 0){
            itemDom.css({
                'background-color': '#D8F3B3',
                '-webkit-box-shadow': '1px 1px 1px',
                '-moz-box-shadow': '1px 1px 1px',
                'box-shadow': '1px 1px 1px',
                '-moz-border-radius': '15px',      /* Gecko browsers */
                '-webkit-border-radius': '15px',   /* Webkit browsers */
                'border-radius':'15px'            /* W3C syntax */
            });
            itemFieldDom.css({
                'background-color': '#D8F3B3'
            });
        }else{
            itemDom.css({
                'background-color': '#F3D97E'
            });
            itemFieldDom.css({
                'background-color': '#F3D97E'
            });
        }


        if(item.fieldType == 'object' || item.fieldType == 'array'){

            changeItemObject(index+1, item, itemDom);
        }



        parentDom.append(itemDom);
    }

}

/**
 * 生成option的请求demo
 * @param option
 * @param optionDom
 * @param method
 */
function changeJSONPreview(option, optionDom, method, module, api){

    if(option.value == 'request'){
        // 使用option的items构造JSON字符串
        if(method == 'GET'){
            var url = ProjectURL + module.mapping + '/' + api.mapping + "?token=yourtokenID&t="+new Date().getTime();
            var post = parseJSONObjectByItems(option.items);

            for(var key in post){
                var value = post[key];
                if(value instanceof Object){
                    value = '{object}';
                }else if(value instanceof  Array){
                    value = '[array]';
                }

                url += '&'+key+'='+value;
            }

            var optionDemoDom = $('<div class="option_demo demoitem"></div>');

            var optionDemoNameDom = $('<div class="option_name">JSON DEMO</div>');
            var optionURLDom = $('<div class="option_url"><span>URL</span>'+url+'</div>');

            optionDemoDom.append(optionDemoNameDom).append(optionURLDom);


            optionDom.append(optionDemoDom);

        }else if(method == 'POST'){
            // 在post模式下构造请求URL和参数对象
            var url = ProjectURL + module.mapping + '/' + api.mapping + "?token=yourtokenID&t="+new Date().getTime();
            var post = parseJSONObjectByItems(option.items);


            var optionDemoDom = $('<div class="option_demo demoitem"></div>');

            var optionDemoNameDom = $('<div class="option_name">JSON DEMO</div>');
            var optionURLDom = $('<div class="option_url"><span>URL</span>'+url+'</div>');
            var optionPOSTDom = $('<div class="option_post"><span>POST</span>'+JSON.stringify(post)+'</div>');


            optionDemoDom.append(optionDemoNameDom).append(optionURLDom).append(optionPOSTDom);


            optionDom.append(optionDemoDom);

        }
    }else if(option.value == 'success'){
        var post = {
            result: true,
            msg: '',
            api: module.mapping + '/' + api.mapping,
            payload: parseJSONObjectByItems(option.items)
        }

        var optionDemoDom = $('<div class="option_demo demoitem"></div>');

        var optionDemoNameDom = $('<div class="option_name">JSON DEMO</div>');
        var optionPOSTDom = $('<div class="option_successresponse"><span>Success Response</span>'+JSON.stringify(post)+'</div>');

        optionDemoDom.append(optionDemoNameDom).append(optionPOSTDom);


        optionDom.append(optionDemoDom);



    }else if(option.value == 'error'){
        var post = {
            result: false,
            msg: option.items[0].desc,
            ecode: parseInt(option.items[0].name),
            api: module.mapping + '/' + api.mapping,
            debug: {
                exception: ''
            }
        }

        var optionDemoDom = $('<div class="option_demo demoitem"></div>');

        var optionDemoNameDom = $('<div class="option_name">JSON DEMO</div>');
        var optionPOSTDom = $('<div class="option_errorresponse"><span>Error Response</span>'+JSON.stringify(post)+'</div>');

        optionDemoDom.append(optionDemoNameDom).append(optionPOSTDom);


        optionDom.append(optionDemoDom);
    }
}

/**
 * 根据 items数组 返回JSON对象
 * @param items
 */
function parseJSONObjectByItems(items){
    if(!items){
        return null;
    }

    var object = {};
    // 遍历option
    for(var i = 0 ; i < items.length ; i ++){
        var item = items[i];

        switch (item.fieldType){
            case 'object':
                object[item.name] = parseJSONObjectByItems(item.plus);
                break;
            case 'array':
                object[item.name] = parseJSONArrayByItems(item.plus);
                break;
            case 'int':
                object[item.name] = parseInt(item.defaultValue);
                break;
            case 'boolean':
                if(item.defaultValue == 'true'){
                    object[item.name] = true;
                }else{
                    object[item.name] = false;
                }
                break;
            default :
                object[item.name] = item.defaultValue;
                break;
        }

    }

    return object;
}

/**
 * 根据 items数组 返回数组对象
 * @param items
 * @returns {Array}
 */
function parseJSONArrayByItems(items){
    if(!items){
        return [];
    }
    var object = {};
    var res = [];
    // 遍历option
    for(var i = 0 ; i < items.length ; i ++){
        var item = items[i];

        switch (item.fieldType){
            case 'object':
                object[item.name] = (parseJSONObjectByItems(item.plus));
                break;
            case 'array':
                object[item.name] = (parseJSONArrayByItems(item.plus));
                break;
            case 'int':
                object[item.name] = (parseInt(item.defaultValue));
                break;
            case 'boolean':
                if(item.defaultValue == 'true'){
                    object[item.name] = true;
                }else{
                    object[item.name] = false;
                }
                break;
            default :
                object[item.name] = item.defaultValue;
                break;
        }

    }
    res.push(object);
    return res;
}